package pl.edu.agh.winmon.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import pl.edu.agh.winmon.hibernate.Process;
import pl.edu.agh.winmon.hibernate.Program;
import pl.edu.agh.winmon.hibernate.Session;
import pl.edu.agh.winmon.hibernate.Turn;

public class SessionDAO extends AbstractDAOSupport {

	/**
	 * Constructor.
	 * 
	 * @param sessionFactory
	 *            Hibernate's {@link SessionFactory} which manages communication
	 *            with database.
	 */
	public SessionDAO(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	@SuppressWarnings("unchecked")
	public List<Session> getSessions() {
		Transaction transaction = sessionFactory.getCurrentSession()
				.beginTransaction();
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Session.class);
		List<Session> result = (List<Session>) criteria.list();
		transaction.commit();
		return result;
	}

	public Session getSession(long startTime) {
		Transaction transaction = sessionFactory.getCurrentSession()
				.beginTransaction();
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Session.class);
		criteria.add(Restrictions.ge(Session.PROP_START_TIME, startTime));
		Session result = (Session) criteria.list().get(0);
		result.getTurns().size();
		result.getPrograms().size();
		for (Turn t : result.getTurns()) {
			if (t != null) {
				t.getCpusLoads().size();
				t.getProcessesStatEntry().size();
				t.getMemoryStatEntry();
			}
		}
		for (Program prog : result.getPrograms()) {
			if (prog != null) {
				prog.getProcesses().size();
				for (Process p : prog.getProcesses()) {
					if (p != null) {
						p.getStatEntries().size();
					}
				}
			}
		}
		transaction.commit();
		return result;
	}

	public Session getLastSession() {
		Transaction transaction = sessionFactory.getCurrentSession()
				.beginTransaction();
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(
				Session.class);

		criteria.addOrder(Property.forName(Session.PROP_START_TIME).desc());
		Session result = (Session) criteria.list().get(0);
		result.getTurns().size();
		result.getPrograms().size();
		for (Turn t : result.getTurns()) {
			t.getCpusLoads().size();
			t.getProcessesStatEntry().size();
			t.getMemoryStatEntry();
		}

		for (Program prog : result.getPrograms()) {
			prog.getProcesses().size();
		}
		transaction.commit();
		return result;
	}
}
